<?php
namespace app\common\service;

/**
 * 微信api
 * Class Wxapi
 * @package app\common\service
 */
class WxApi{


    /**
     * 构造函数
     * 2019-12-10
     */
    public function __construct(){

        $this->sessionKey_url="https://api.weixin.qq.com/sns/jscode2session";
        $this->accessToken_url="https://api.weixin.qq.com/cgi-bin/token";
        $this->jsapi_ticket_url="https://api.weixin.qq.com/cgi-bin/ticket/getticket";
        $this->qrcodeUrl="https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode";
        $this->Configuration = app('app\common\model\system\Configuration');
    }

    /**
     * 获取access_token
     * 2019-12-10
     *
     * @param string  appid         appid
     * @param string  appsecret     appsecret
     * @param string  tableName     表名（wx_account）
     * @return string token         token
     */
    public function getToken($appid,$appsecret){
        $accountInfo = $this->Configuration->where('key','wechat_token')->field('val,create_time')->find();

        $now_time = time();//当前时间戳
        if(empty($accountInfo)){
            return false;
        }

        if($now_time-strtotime($accountInfo->create_time)<7000){
            $token = $accountInfo->val;

            return $token;

        }else{

            $get_token_url = $this->accessToken_url."?grant_type=client_credential&appid=".$appid.'&secret='.$appsecret;
            $getToken_json = $this->curl_get($get_token_url);

            $getToken_arr = json_decode($getToken_json,true);

            $token = $getToken_arr['access_token'];

            $arr = [
                'val'=>$token,
                'update_time'=>time(),
                'create_time'=>time()
            ];
            $res = $this->Configuration->where('key','wechat_token')->update($arr);
            if($res){
                return $token;
            }else{
                return false;
            }
        }
    }

    public  function curl_get($url)
    {

        //初始化
        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL,$url);
        // 执行后不直接打印出来
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HEADER, false);
        // 跳过证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // 不从证书中检查SSL加密算法是否存在
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);

        //执行并获取HTML文档内容
        $output = curl_exec($ch);

        //释放curl句柄
        curl_close($ch);

        return $output;
    }
    public  function http_post($access_token,$data)
    {
        $url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=".$access_token;

        $ch = curl_init();

        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $res = curl_exec($ch);
        curl_close($ch);
        return $res;
    }
    /**
     * 获取jssdk-ticket
     *
     * @param string  appid         appid
     * @param string  appsecret     appsecret
     * @param string  tableName     表名（wx_account）
     * @return string token         token
     */
    public function getJssdkTicket($appid,$appsecret){

        $accountInfo = $this->Configuration->where('key','jsapi_ticket')->field('val,create_time')->find();

        if(empty($accountInfo)){
            return false;
        }

        $now_time = time();//当前时间戳

        if($now_time-strtotime($accountInfo->create_time)<7000){
            $jsapi_ticket = $accountInfo->val;
            return $jsapi_ticket;
        }else{
            $access_token=$this->getToken($appid,$appsecret);

            if(!$access_token){
                return false;
            }


            $get_jsapi_ticket_url = $this->jsapi_ticket_url."?access_token=".$access_token."&type=jsapi";
            $getJssdkTicket_json = $this->curl_get($get_jsapi_ticket_url);
            $getJssdkTicket_arr = json_decode($getJssdkTicket_json,true);

            $jsapi_ticket = $getJssdkTicket_arr['ticket'];

            $arr = [
                'val'=>$jsapi_ticket,
                'update_time'=>time(),
                'create_time'=>time(),
            ];
            $res = $this->Configuration->where('key','jsapi_ticket')->update($arr);
            if($res){
                return $jsapi_ticket;
            }else{
                return false;
            }
        }
    }

    /**
     * 获取签名包
     * @return array
     */
    public function getSignPackage($appid,$appsecret,$url) {
        $jsapiTicket = $this->getJssdkTicket($appid,$appsecret);


        // 注意 URL 一定要动态获取，不能 hardcode.
        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
        //$url = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";

        $timestamp = time();
        $nonceStr = $this->createNonceStr();

        // 这里参数的顺序要按照 key 值 ASCII 码升序排序
        $string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url";


        $signature = sha1($string);

        $signPackage = array(
            "appId"     => $appid,
            "nonceStr"  => $nonceStr,
            "timestamp" => $timestamp,
            "url"       => $url,
            "signature" => $signature,
            "rawString" => $string
        );
        return $signPackage;
    }

    public function createNonceStr($length = 16) {
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        $str = "";
        for ($i = 0; $i < $length; $i++) {
            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
        }
        return $str;
    }
}


?>